package emulator.util;

import java.io.PrintStream;

import emulator.EmulatorException;
import emulator.hardware.HwByte;
import emulator.hardware.HwWord;
import emulator.hardware.bus.Bus;

public class AddressRange {
	int start = 0;
	int end = 0;
	/**
	 * @return the start
	 */
	public int getStart() {
		return start;
	}
	/**
	 * @param start the start to set
	 */
	public void setStart(int start) {
		this.start = start;
	}
	/**
	 * @return the end
	 */
	public int getEnd() {
		return end;
	}
	/**
	 * @param end the end to set
	 */
	public void setEnd(int end) {
		this.end = end;
	}
	
	static public AddressRange fromString(String string) {
		AddressRange result = new AddressRange();
		String [] addresses = string.split("-");
		result.setStart(addressFromString(addresses[0]));
		if (addresses.length > 1)
			result.setEnd(addressFromString(addresses[1]));
		else
			result.setEnd(addressFromString(addresses[0]));
		return result;
	}
	
	public static int addressFromString(String string) {
		if (string.length() > 0)
		{
			if (string.charAt(0) == '$')
			{
				String ucstr = string.toUpperCase();
				String digits = "0123456789ABCDEF";
				int val = 0;
				for (int i = 1; i < ucstr.length(); i++)
				{
					val <<= 4;
					int digit = digits.indexOf(ucstr.charAt(i));
					if (digit < 0)
						throw new NumberFormatException(string);
					val |= digit;
				}
				return val;
			}
			else if (string.charAt(0) == '%')
			{
				int val = 0;
				for (int i = 1; i < string.length(); i++)
				{
					val <<= 1;
					if (string.charAt(i) == '1')
						val |= 1;
					else if (string.charAt(i) != '0')
						throw new NumberFormatException(string);
				}
				return val;
			}
			else
				return Integer.parseInt(string);
		}
		return 0;
	}
	
	public void printMemory(Bus bus, PrintStream out)
	{
		int first_line = getStart() & ~0xF;
		int last_line = getEnd() & ~0xF;
		for (int line = first_line; line <= last_line; line += 16)
		{
			String text = new String();
			HwWord base = new HwWord(line);
			out.print(base.toString()+":  ");
			for (int i = 0; i < 16; i++)
			{
				if (base.getNumber() < getStart()
					|| base.getNumber() > getEnd())
				{
					out.print("   ");
					text += " ";
				}
				else
				{
					try {
						HwByte data = new HwByte(bus.read((int) base.getNumber()));
						out.print(data.toString()+" ");
						if (data.getNumber() >= 32 && data.getNumber() < 128)
							text += (char) data.getNumber();
						else
							text += ".";
					} catch (EmulatorException e) {
						out.print("?? ");
						text += ".";
					}
				}
				base.inc(1);
			}
			out.println(" "+text);
		}
	}
}
